use anyhow::{anyhow, Result};
use once_cell::sync::Lazy;
use std::path::Path;
use std::sync::{Arc, Mutex};
use tauri::AppHandle;

pub(crate) static APP: Lazy<Arc<Mutex<Option<AppHandle>>>> =
    Lazy::new(|| Arc::new(Mutex::new(None)));

pub fn set_app(app: AppHandle) -> Result<()> {
    let mut app_lock = APP.lock().unwrap();
    *app_lock = Some(app);
    Ok(())
}

pub fn get_app() -> Result<AppHandle> {
    let app_handle = {
        let app_lock = APP.lock().unwrap();
        if let Some(app) = app_lock.as_ref() {
            app.clone() // 克隆句柄
        } else {
            return Err(anyhow!("App not initialized"));
        }
    };
    Ok(app_handle)
}

#[tauri::command]
pub fn open_file(path: String) {
    let path = Path::new(&path);
    if path.exists() {
        if let Some(path) = path.to_str() {
            if let Err(err) = open(path) {
                eprintln!("open failed:: {:?}", err);
            }
        }
    } else {
        open_folder(path.to_str().unwrap().to_string())
    }
}

#[tauri::command]
pub fn open_folder(path: String) {
    let out_path = Path::new(&path);

    let path = if out_path.is_file() || !out_path.exists() {
        let parent = out_path.parent().unwrap();
        parent.to_str().unwrap_or(&path)
    } else {
        out_path.to_str().unwrap_or(&path)
    };

    if let Err(err) = open(path) {
        eprintln!("open failed:: {:?}", err);
    }
}

fn open(path: &str) -> Result<()> {
    if cfg!(target_os = "windows") {
        std::process::Command::new("explorer").arg(path).spawn()?;
    } else if cfg!(target_os = "macos") {
        std::process::Command::new("open").arg(path).spawn()?;
    } else if cfg!(target_os = "linux") {
        std::process::Command::new("xdg-open").arg(path).spawn()?;
    }

    Ok(())
}
